// file: handlers/control_panel.go
package handlers

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strconv"
	"sync"
	"time"
)

// ControlPanelConfig 接收控制面板的配置
type ControlPanelConfig struct {
	SystemUrlPort   int    `json:"system_url_port"`
	SystemDevMode   bool   `json:"system_dev_mode"`
	UseLocalNetwork bool   `json:"use_local_network"`
	PortRelease     bool   `json:"port_release"`
	ModelSystemPort int    `json:"model_system_port"`
	ModelUrlPort    int    `json:"model_url_port"`
	ModelFilePath   string `json:"model_file_path"`
	// 模型文件路径参数
	ModelEmbeddingIndex string `json:"model_embedding_index"`
	ModelReasoningIndex string `json:"model_reasoning_index"`
	ModelVisualingIndex string `json:"model_visualing_index"`
	// 打包功能参数
	OutBase          string `json:"out_base"`
	PartSizeMB       int    `json:"part_size_mb"`
	CompressionLevel int    `json:"compression_level"`
	PackageLevel     int    `json:"package_level"`
}

var (
	// 存储当前运行的进程
	currentProcess *os.Process
	processMutex   sync.Mutex
)

// ControlPanelStartHandler 处理启动服务的请求
func ControlPanelStartHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "控制面板[ERROR] -> 不允许的请求方法", http.StatusMethodNotAllowed)
		return
	}

	var config ControlPanelConfig
	if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
		http.Error(w, fmt.Sprintf("控制面板[ERROR] -> 解析配置失败: %v", err), http.StatusBadRequest)
		return
	}

	// 构建命令行参数
	args := buildCommandArgs(config)

	// 启动进程
	pid, err := startAgentProcess(args)
	if err != nil {
		http.Error(w, fmt.Sprintf("控制面板[ERROR] -> 启动进程失败: %v", err), http.StatusInternalServerError)
		return
	}

	response := map[string]interface{}{
		"success": true,
		"pid":     pid,
		"message": "服务启动成功",
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(response)

	log.Printf("控制面板 -> 启动服务成功, PID: %d, 参数: %v", pid, args)
}

// ControlPanelStopHandler 处理停止服务的请求
func ControlPanelStopHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "控制面板[ERROR] -> 不允许的请求方法", http.StatusMethodNotAllowed)
		return
	}

	processMutex.Lock()
	defer processMutex.Unlock()

	if currentProcess == nil {
		response := map[string]interface{}{
			"success": false,
			"error":   "没有正在运行的服务",
		}
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
		return
	}

	// 终止进程
	if err := currentProcess.Kill(); err != nil {
		response := map[string]interface{}{
			"success": false,
			"error":   fmt.Sprintf("终止进程失败: %v", err),
		}
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
		return
	}

	currentProcess = nil

	response := map[string]interface{}{
		"success": true,
		"message": "服务已停止",
	}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(response)

	log.Printf("控制面板 -> 服务已停止")
}

// buildCommandArgs 根据配置构建命令行参数
func buildCommandArgs(config ControlPanelConfig) []string {
	args := []string{}

	// 添加系统配置参数
	if config.SystemUrlPort != 0 {
		args = append(args, "-system_url_port", strconv.Itoa(config.SystemUrlPort))
	}

	if config.SystemDevMode {
		args = append(args, "-system_dev_mode")
	}

	if config.UseLocalNetwork {
		args = append(args, "-use_local_network")
	}

	if config.PortRelease {
		args = append(args, "-port_release")
	}

	// 添加模型配置参数
	if config.ModelSystemPort != 0 {
		args = append(args, "-model_system_port", strconv.Itoa(config.ModelSystemPort))
	}

	if config.ModelUrlPort != 0 {
		args = append(args, "-model_url_port", strconv.Itoa(config.ModelUrlPort))
	}

	if config.ModelFilePath != "" {
		args = append(args, "-model_file_path", config.ModelFilePath)
	}

	// 添加模型文件路径参数
	if config.ModelEmbeddingIndex != "" {
		args = append(args, "-model_embedding_index", config.ModelEmbeddingIndex)
	}

	if config.ModelReasoningIndex != "" {
		args = append(args, "-model_reasoning_index", config.ModelReasoningIndex)
	}

	if config.ModelVisualingIndex != "" {
		args = append(args, "-model_visualing_index", config.ModelVisualingIndex)
	}

	// 添加打包功能参数
	if config.OutBase != "" {
		args = append(args, "-out", config.OutBase)
	}

	if config.PartSizeMB != 0 {
		args = append(args, "-size", strconv.Itoa(config.PartSizeMB))
	}

	if config.CompressionLevel != 0 {
		args = append(args, "-compression", strconv.Itoa(config.CompressionLevel))
	}

	if config.PackageLevel != 0 {
		args = append(args, "-level", strconv.Itoa(config.PackageLevel))
	}

	return args
}

// startAgentProcess 启动 Lunar-Astral-Agents.exe 进程
func startAgentProcess(args []string) (int, error) {
	processMutex.Lock()
	defer processMutex.Unlock()

	// 如果已有进程在运行，先终止
	if currentProcess != nil {
		currentProcess.Kill()
		currentProcess = nil
		time.Sleep(2 * time.Second) // 等待进程完全退出
	}

	// 获取当前可执行文件路径
	execPath, err := os.Executable()
	if err != nil {
		return 0, fmt.Errorf("获取可执行文件路径失败: %v", err)
	}

	var cmd *exec.Cmd
	if runtime.GOOS == "windows" {
		// Windows 系统
		cmd = exec.Command(execPath, args...)
	} else {
		// 其他系统
		cmd = exec.Command("./"+filepath.Base(execPath), args...)
	}

	// 设置输出到当前控制台
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	// 启动进程
	if err := cmd.Start(); err != nil {
		return 0, fmt.Errorf("启动进程失败: %v", err)
	}

	currentProcess = cmd.Process

	// 启动一个goroutine来等待进程结束并清理
	go func() {
		cmd.Wait()
		processMutex.Lock()
		currentProcess = nil
		processMutex.Unlock()
		log.Printf("控制面板 -> 服务进程已退出")
	}()

	return cmd.Process.Pid, nil
}

// ControlPanelCompileHandler 处理编译项目的请求
func ControlPanelCompileHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "控制面板[ERROR] -> 不允许的请求方法", http.StatusMethodNotAllowed)
		return
	}

	// 首先停止当前运行的服务
	processMutex.Lock()
	if currentProcess != nil {
		currentProcess.Kill()
		currentProcess = nil
		log.Printf("控制面板 -> 已停止当前服务进程")
	}
	processMutex.Unlock()

	// 等待进程完全退出
	time.Sleep(2 * time.Second)

	var config ControlPanelConfig
	if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
		http.Error(w, fmt.Sprintf("控制面板[ERROR] -> 解析配置失败: %v", err), http.StatusBadRequest)
		return
	}

	// 执行编译命令
	output, err := compileProject()
	if err != nil {
		response := map[string]interface{}{
			"success": false,
			"error":   fmt.Sprintf("编译失败: %v", err),
		}
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
		return
	}

	response := map[string]interface{}{
		"success": true,
		"message": "项目编译成功",
		"output":  output,
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(response)

	log.Printf("控制面板 -> 项目编译成功")
}

// compileProject 执行 go build 命令编译项目
func compileProject() (string, error) {
	// 获取当前工作目录
	wd, err := os.Getwd()
	if err != nil {
		return "", fmt.Errorf("获取工作目录失败: %v", err)
	}

	// 构建编译命令
	var cmd *exec.Cmd
	if runtime.GOOS == "windows" {
		cmd = exec.Command("go", "build", "-o", "Lunar-Astral-Agents.exe")
	} else {
		cmd = exec.Command("go", "build", "-o", "Lunar-Astral-Agents")
	}

	cmd.Dir = wd

	// 捕获输出
	var output bytes.Buffer
	cmd.Stdout = &output
	cmd.Stderr = &output

	// 执行编译
	if err := cmd.Run(); err != nil {
		return output.String(), fmt.Errorf("编译命令执行失败: %v", err)
	}

	return output.String(), nil
}
